package com.inspur.edp.bef.deployer;

import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.util.ReferenceService;
import com.inspur.edp.cef.entity.changeset.Tuple;
import com.inspur.edp.lcm.metadata.api.entity.DeploymentContext;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataPackage;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.lcm.project.deployer.spi.DeployAction;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import javax.transaction.Transactional;
import java.io.File;
import java.util.ArrayList;


public class BefDeployService implements DeployAction {

    public final void deploy(DeploymentContext context) {
        java.util.List<Tuple<String, java.util.ArrayList<GspMetadata>>> bemetadatas = getBEMetadatas(context);
        deployBE(context, bemetadatas);
    }

    @Transactional
    public void deployBE(DeploymentContext context, java.util.List<Tuple<String, ArrayList<GspMetadata>>> bemetadatas) {
        if (bemetadatas == null) {
            return;
        }
        for (Tuple<String, ArrayList<GspMetadata>> pair : bemetadatas) {
            for (GspMetadata metadata : pair.getItem2()) {
                ConfigReference(context, pair.getItem1(), metadata);
            }
        }
    }


    private java.util.List<Tuple<String, java.util.ArrayList<GspMetadata>>> getBEMetadatas(DeploymentContext context) {
        java.util.ArrayList<Tuple<String, java.util.ArrayList<GspMetadata>>> result = new java.util.ArrayList<Tuple<String, java.util.ArrayList<GspMetadata>>>();
        ArrayList<String> fileList = new ArrayList<>();
        getMdpkgPaths(context.getPublishPath(), fileList);
        for (String path : fileList) {
            java.util.ArrayList<GspMetadata> bemetadatas = new java.util.ArrayList<GspMetadata>();
            MetadataService service = SpringBeanUtils.getBean(MetadataService.class);
            String fileNameWithoutExtension = getFileNameWithoutExtension(path);
            String directoryName = getDirectoryName(path);
            MetadataPackage metadataPackageInfo = service.getMetadataPackageInfo(fileNameWithoutExtension, directoryName);
            String su = null;
            if (metadataPackageInfo != null && metadataPackageInfo.getServiceUnitInfo() != null) {
                su = metadataPackageInfo.getServiceUnitInfo().getServiceUnitCode();
            }
            if (su == null || "".equals(su)) {
                continue;
            }
            java.util.List<GspMetadata> metadataList = metadataPackageInfo.getMetadataList();
            for (GspMetadata item : metadataList) {
                if (!("GspBusinessEntity").equals(item.getHeader().getType())) {
                    continue;
                }
                GspMetadata beMetadata = getMdContent(fileNameWithoutExtension, directoryName, item.getHeader().getId());
                bemetadatas.add(beMetadata);
            }
            if (bemetadatas == null) {
                result.add(new Tuple<String, java.util.ArrayList<GspMetadata>>(metadataPackageInfo.getServiceUnitInfo().getServiceUnitCode(), bemetadatas));
            }
        }

        return result;
    }

    private String getDirectoryName(String path) {
        return (new File(path)).getParent();
    }

    private ArrayList<String> getMdpkgPaths(String path, ArrayList<String> list) {

        File file = new File(path);
        File[] array = file.listFiles();

        for (int i = 0; i < array.length; i++) {
            if (array[i].isFile()) {
                if (array[i].getPath().endsWith("mdpkg")) {
                    list.add(array[i].getPath());
                }
            } else if (array[i].isDirectory()) {
                getMdpkgPaths(array[i].getPath(), list);
            }
        }
        return list;
    }

    private String getFileNameWithoutExtension(String path) {
        File file = new File(path);
        String fileName;
        if (file.isDirectory()) {
            fileName = path + " is  a directory";
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_TEMPLATE_ERROR, fileName);
        } else {
            fileName = file.getName();
            int point = fileName.lastIndexOf(".");
            return point == -1 ? fileName : fileName.substring(0, point);
        }
    }

    private GspMetadata getMdContent(String packageName, String packagePath, String metadataID) {
        return SpringBeanUtils.getBean(MetadataService.class).getMetadataFromPackage(packageName, packagePath, metadataID).getMetadata();
    }

    private void ConfigReference(DeploymentContext context, String su, GspMetadata metadata) {
        ReferenceService tempVar = new ReferenceService();
        tempVar.setRefCommonService(SpringBeanUtils.getBean(RefCommonService.class));
        tempVar.setServiceUnitCode(su);
        ReferenceService rs = tempVar;
        rs.registerReference(metadata);
    }


//        private GspMetadata getMdContent(String packageName, String packagePath, String metadataID)
//        {
//            return ServiceManager.<IMetadataService>GetService().GetMetadataFromPackage(packageName, packagePath, metadataID).Metadata;
//        }

//        public final GspMetadata GetMetadata(String mdId)
//        {
//            java.util.ArrayList<GspMetadata> bemetadatas = new java.util.ArrayList<GspMetadata>();
////            String[] files = Directory.GetFiles(context.ProjectPath, "*.mdpkg", SearchOption.AllDirectories);
//            ArrayList<String> files=getMdpkgPaths(context.getPublishPath());
//            for (String path : files)
//            {
//                MetadataService service =SpringBeanUtils.getBean(MetadataService.class);
//
//                String fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
//                String directoryName = Path.GetDirectoryName(path);
//                GspMetadata metadata = getMdContent(fileNameWithoutExtension, directoryName, mdId);
//                if (metadata != null)
//                {
//                    return metadata;
//                }
//            }
////C# TO JAVA CONVERTER TODO TASK: There is no equivalent to implicit typing in Java:
//            var org = RefCommonContext.IsInvokeAtDesignTime;
//            RefCommonContext.IsInvokeAtDesignTime = false;
//            try
//            {
//                return ServiceManager.<IRefCommonService>GetService().GetRefMetadata(mdId);
//            }
//            finally
//            {
//                RefCommonContext.IsInvokeAtDesignTime = org;
//            }
//        }
//        }
}
